package br.com.sgc.session;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;

import javax.ejb.EJB;
import javax.ejb.Stateless;

import br.com.sgc.dao.PedidoVendaDao;
import br.com.sgc.entities.financeiro.ItemVenda;
import br.com.sgc.entities.financeiro.PedidoVenda;
import br.com.sgc.entities.geral.Cliente;
import br.com.sgc.entities.geral.Clinica;
import br.com.sgc.entities.produto.ComposicaoProduto;
import br.com.sgc.entities.produto.Produto;
import br.com.sgc.entities.produto.ProdutoComposto;
import br.com.sgc.entities.produto.ProdutoFinal;
import br.com.sgc.enuns.TipoOrdenacao;
import br.com.sgc.exception.ValidacaoException;

@Stateless
public class PedidoVendaSession extends GenericSession<PedidoVenda> {

	private static final long serialVersionUID = 4661870885878654225L;
	
	@EJB private PedidoVendaDao dao;
	
	@EJB private GenericSession<ItemVenda> itemVendaSession;
	
	@EJB private ProdutoSession produtoSession;
	
	@EJB private ProdutoFinalSession produtoFinalSession;
	
	@EJB private GenericSession<ComposicaoProduto> composicaoProdutoSession;
	
	@EJB private CaixaSession caixaSession;
	
	public PedidoVenda fillPedidoVenda(PedidoVenda pedidoVenda, Cliente cliente, Clinica clinica, Boolean finalizado, Boolean cancelado, Boolean guardado) {
		if(pedidoVenda.getId() != null){
			pedidoVenda = dao.findById(PedidoVenda.class, pedidoVenda.getId(), true);
		} else {
			pedidoVenda.setCliente(cliente);
			pedidoVenda.setClinica(clinica);
			pedidoVenda.setValorDesconto(new BigDecimal(0.0));
			calculateNumeroPedido(pedidoVenda);
			pedidoVenda.setDataVenda(new Date());
		}
		pedidoVenda.setFinalizado(finalizado);
		pedidoVenda.setGuardado(guardado);
		pedidoVenda.setCancelado(cancelado);
		dao.detach(pedidoVenda);
		
		return pedidoVenda;
		
	}

	private void calculateNumeroPedido(PedidoVenda pedido) {
		if(pedido.getNumeroPedido() == null && pedido.getIndexNumeroPedido() == null){
			pedido.setIndexNumeroPedido(dao.findLastIndex()+1);
			pedido.setNumeroPedido(pedido.getIndexNumeroPedido()+"-PED");
		}
	}
	
	public List<PedidoVenda> findAll(PedidoVenda modelClass, Long clinicaId,
			Integer startPage, Integer maxPage, String orderField,
			Boolean initializeDependecies, TipoOrdenacao ordenacao) {
		return dao.findAll(modelClass, clinicaId, startPage, maxPage, orderField,
				initializeDependecies, ordenacao);
	}
	
	@Override
	public Long count(PedidoVenda modelClass, Long clinicaId) {
		return dao.count(modelClass, clinicaId);
	}

	public void atualizarEstoque(PedidoVenda pedidoVenda) throws ValidacaoException {
		pedidoVenda = dao.findById(PedidoVenda.class, pedidoVenda.getId(), true);
		
		for(ItemVenda item: pedidoVenda.getProdutos()){
			item = itemVendaSession.findById(ItemVenda.class, item.getId(), true);
			
			Produto produto = produtoSession.findById(Produto.class, item.getProduto().getId());
			
			if(produto instanceof ProdutoFinal){
				produto = (ProdutoFinal) produtoFinalSession.findById(ProdutoFinal.class, produto.getId());
				((ProdutoFinal) produto).setEstoqueAtual(((ProdutoFinal) produto).getEstoqueAtual()-item.getQuantidade());
				produtoFinalSession.update((ProdutoFinal)produto);
				
			} else if(produto instanceof ComposicaoProduto){
				
				produto = (ComposicaoProduto) composicaoProdutoSession.findById(ComposicaoProduto.class, produto.getId(), true);
				
				for(ProdutoComposto p: ((ComposicaoProduto) produto).getProdutoComposto()){
					if(p.getProduto() != null){
						ProdutoFinal prd = (ProdutoFinal) produtoFinalSession.findById(ProdutoFinal.class, p.getProduto().getId());
						prd.setEstoqueAtual(prd.getEstoqueAtual()-p.getQuantidadeProduto().doubleValue());
						produtoFinalSession.update(prd);
					}
				}
				
			}
			
		}
	}
	
	public void addEstoque(PedidoVenda pedidoVenda) throws ValidacaoException {
		pedidoVenda = dao.findById(PedidoVenda.class, pedidoVenda.getId(), true);
		
		for(ItemVenda item: pedidoVenda.getProdutos()){
			item = itemVendaSession.findById(ItemVenda.class, item.getId(), true);
			
			Produto produto = produtoSession.findById(Produto.class, item.getProduto().getId());
			
			if(produto instanceof ProdutoFinal){
				produto = (ProdutoFinal) produtoFinalSession.findById(ProdutoFinal.class, produto.getId());
				((ProdutoFinal) produto).setEstoqueAtual(((ProdutoFinal) produto).getEstoqueAtual()+item.getQuantidade());
				produtoFinalSession.update((ProdutoFinal)produto);
				
			} else if(produto instanceof ComposicaoProduto){
				
				produto = (ComposicaoProduto) composicaoProdutoSession.findById(ComposicaoProduto.class, produto.getId(), true);
				
				for(ProdutoComposto p: ((ComposicaoProduto) produto).getProdutoComposto()){
					if(p.getProduto() != null){
						ProdutoFinal prd = (ProdutoFinal) produtoFinalSession.findById(ProdutoFinal.class, p.getProduto().getId());
						prd.setEstoqueAtual(prd.getEstoqueAtual()+p.getQuantidadeProduto().doubleValue());
						produtoFinalSession.update(prd);
					}
				}
				
			}
			
		}
	}
	
	@Override
	public PedidoVenda save(PedidoVenda t) throws ValidacaoException {
		caixaSession.caixaFechado(t.getClinica());
		return dao.insert(t);
	}
	
	@Override
	public PedidoVenda update(PedidoVenda t) throws ValidacaoException {
		caixaSession.caixaFechado(t.getClinica());
		return dao.update(t);
	}
	
	public PedidoVenda cancelar(PedidoVenda t) throws ValidacaoException {
		caixaSession.caixaFechado(t.getClinica());
		addEstoque(t);
		return dao.update(t);
	}

}
